using OracleInternal.MTS;
using OracleInternal.TTC;

namespace OracleInternal.ServiceObjects
{
	internal class MTSTransactionImpl
	{
		internal static void Start(OracleConnectionImpl connImpl, OpoDTCTxnCtx opoTxnCtx, uint timeout)
		{
			try
			{
				connImpl.m_connectionFreeToUseEvent.WaitOne();
				TTCTransactionSE tTCTransactionSE = connImpl.TTCTransactionSE;
				connImpl.AddAllPiggyBackRequests();
				opoTxnCtx.m_txnCtx = tTCTransactionSE.Start(opoTxnCtx.m_opoDTCTxnXID, opoTxnCtx.m_txnCtx, timeout, ref opoTxnCtx.m_applicationValue);
			}
			finally
			{
				connImpl.m_connectionFreeToUseEvent.Set();
			}
		}

		internal static void Resume(OracleConnectionImpl connImpl, OpoDTCTxnCtx opoTxnCtx, uint timeout)
		{
			try
			{
				connImpl.m_connectionFreeToUseEvent.WaitOne();
				TTCTransactionSE tTCTransactionSE = connImpl.TTCTransactionSE;
				connImpl.AddAllPiggyBackRequests();
				opoTxnCtx.m_txnCtx = tTCTransactionSE.Resume(opoTxnCtx.m_opoDTCTxnXID, opoTxnCtx.m_txnCtx, timeout, ref opoTxnCtx.m_applicationValue);
			}
			finally
			{
				connImpl.m_connectionFreeToUseEvent.Set();
			}
		}

		internal static void Promote(OracleConnectionImpl connImpl, OpoDTCTxnCtx opoTxnCtx, uint timeout)
		{
			try
			{
				connImpl.m_connectionFreeToUseEvent.WaitOne();
				TTCTransactionSE tTCTransactionSE = connImpl.TTCTransactionSE;
				connImpl.AddAllPiggyBackRequests();
				opoTxnCtx.m_txnCtx = tTCTransactionSE.Promote(opoTxnCtx.m_opoDTCTxnXID, opoTxnCtx.m_txnCtx, timeout, ref opoTxnCtx.m_applicationValue);
			}
			finally
			{
				connImpl.m_connectionFreeToUseEvent.Set();
			}
		}

		internal static void Detach(OracleConnectionImpl connImpl, OpoDTCTxnCtx opoTxnCtx, uint timeout)
		{
			try
			{
				connImpl.m_connectionFreeToUseEvent.WaitOne();
				TTCTransactionSE tTCTransactionSE = connImpl.TTCTransactionSE;
				connImpl.AddAllPiggyBackRequests();
				opoTxnCtx.m_txnCtx = tTCTransactionSE.Detach(opoTxnCtx.m_opoDTCTxnXID, opoTxnCtx.m_txnCtx, timeout, ref opoTxnCtx.m_applicationValue);
			}
			finally
			{
				connImpl.m_connectionFreeToUseEvent.Set();
			}
		}

		internal static TxnState Prepare(OracleConnectionImpl connImpl, OpoDTCTxnCtx opoTxnCtx, uint timeout, bool bMatchConn)
		{
			try
			{
				connImpl.m_connectionFreeToUseEvent.WaitOne();
				TTCTransactionEN tTCTransactionEN = connImpl.TTCTransactionEN;
				connImpl.AddAllPiggyBackRequests();
				return tTCTransactionEN.Prepare(opoTxnCtx.m_opoDTCTxnXID, opoTxnCtx.m_txnCtx, timeout, TxnState.K2CMDprepare);
			}
			finally
			{
				connImpl.m_connectionFreeToUseEvent.Set();
			}
		}

		internal static TxnState Commit(OracleConnectionImpl connImpl, OpoDTCTxnCtx opoTxnCtx, uint timeout, bool bMatchConn)
		{
			try
			{
				connImpl.m_connectionFreeToUseEvent.WaitOne();
				TTCTransactionEN tTCTransactionEN = connImpl.TTCTransactionEN;
				connImpl.AddAllPiggyBackRequests();
				return tTCTransactionEN.Commit(opoTxnCtx.m_opoDTCTxnXID, opoTxnCtx.m_txnCtx, timeout, TxnState.K2CMDcommit);
			}
			finally
			{
				connImpl.m_connectionFreeToUseEvent.Set();
			}
		}

		internal static TxnState Abort(OracleConnectionImpl connImpl, OpoDTCTxnCtx opoTxnCtx, uint timeout, bool bMatchConn)
		{
			try
			{
				connImpl.m_connectionFreeToUseEvent.WaitOne();
				TTCTransactionEN tTCTransactionEN = connImpl.TTCTransactionEN;
				connImpl.AddAllPiggyBackRequests();
				return tTCTransactionEN.Abort(opoTxnCtx.m_opoDTCTxnXID, opoTxnCtx.m_txnCtx, timeout, TxnState.K2CMDabort);
			}
			finally
			{
				connImpl.m_connectionFreeToUseEvent.Set();
			}
		}
	}
}
